<?php

/**
 * Vega Framework
 *
 * @url http://vega.com.vn
 * @url http://clip.vn
 */

/**
 * Vega_Module class
 *
 * Abstract class. Every application module is a subclass of this class.
 */

abstract class Vega_Module
{
    /**
     * Request Object
     */
    protected $_request = null;


    /**
     * Response object
     *
     * @var unknown_type
     */
    protected $_response = null;

    /**
     * Loader
     *
     * @var Vega_Loader
     */
    protected $_loader = null;

    /**
     * Singleton Vega_App instance
     *
     * @var Vega_App
     */
    protected $_app = null;


    /**
     * Module options
     *
     * @var array
     */
    protected $_options = array();


    /**
     * View object
     *
     * @var Vega_View
     */
    protected $_view = null;


    public function __construct(Vega_App $app)
    {
        $this->_app      = $app;
        $this->_loader   = $app->getLoader();
        $this->_request  = $app->getRequest();
        $this->_response = $app->getResponse();
        $this->_view     = $this->_initView();
    }

    protected function _initView()
    {
        $templateDir = $this->_loader->getPath('module', '') . DIRECTORY_SEPARATOR . 'templates';

        require_once 'Vega/View.php';
        $view = new Vega_View($this->_loader);
        $view->setTemplateDir($templateDir);
        $view->setLayoutDir($this->_loader->getAppPath() . DIRECTORY_SEPARATOR . 'layouts');
        return $view;
    }


    /**
     * Sets option.
     * Options are used by other classes
     *
     * @param string $name
     * @param mixed $value
     * @return Vega_Module
     */

    public function setOption($name, $value)
    {
        $this->_options[$name] = $value;
        return $this;
    }

    /**
     * Get option
     *
     * @param string $name
     * @param mixed $else . Returned when the option does not exist
     * @return mixed
     */
    public function getOption($name, $else = null)
    {
        if (!isset($this->_options[$name]))
        {
            return $else;
        }
        return $this->_options[$name];
    }

    /**
     * Return an action method for the given action name
     * @param string $action
     * @return string
     */
    protected function _getActionMethod($action)
    {
        return $action . 'Action';
    }

    /**
     * Dispatch
     *
     * @throw Vega_Module_Exception
     * @return mixed
     */
    public function dispatch()
    {
        $action = $this->_request->getActionName();
        $actionMethod = $this->_getActionMethod($action);
        $module = $this->_request->getModuleName();


        if (!method_exists($this, $actionMethod))
        {
            require_once 'Vega/Module/Exception.php';

            throw new Vega_Module_Exception('Action not implemented', 501);
        }

        $this->_request->setDispatched();
        // pre dispath
        $this->preDispatch();

        $return = call_user_func(array($this, $actionMethod));

        // return if the actions is forwarded
        if ($return instanceof Vega_Request)
        {
            return $return;
        }

        $response = '';

		//perform final modifications to output
		$this->preRenderOutput();

        if (true == $this->getOption('output', true))
        {
            $response = $this->renderOutput();
        }

        $this->postDispatch();

        return $response;
    }

	public function preRenderOutput() {

	}
    /**
    * Render the output
    *
    * @return string
    */
    public function renderOutput()
    {
        $templateFile = $this->getOption('template', $this->_request->getActionName());

        $this->_view->setSkinName($this->getOption('skin', 'default'));
        $this->_view->setLayoutName($this->getOption('layout', 'default'));
        $this->_view->setTemplateFile($templateFile);

        $content = $this->_view->renderTemplate();

        if($this->getOption('use_layout', true))
        {
        	$content = $this->_view->renderLayout($content);
    	}

        $cacheTime = $this->getOption('cache', 0);

        if ($cacheTime > 0)
        {
            $this->_response->setCacheLifetime($cacheTime);
        }

        return $content;
    }


    /**
     * Forward to another action
     *
     * @param string $module
     * @param string $action
     * @return Vega_Request
     */
    public function forward($module, $action)
    {
        $this->_request->setDispatched(false)
                       ->setModuleName($module)
                       ->setActionName($action);
        return $this->_request;
    }

    // TODO improve it
    /**
     * Redirect HTTP redirect
     *
     * @param unknown_type $url
     */
    public function redirect($url)
    {
        ob_clean();
        header('Location: ' . $url);
        die();
    }

    public function preDispatch()
    {

    }

    public function postDispatch()
    {

    }
}
